//
//  YuanXinJSONResponseSerializer.m
//  YuanXinKit
//
//  Created by GJS on 2017/6/23.
//  Copyright © 2017年 GJS. All rights reserved.
//

#import "YuanXinJSONResponseSerializer.h"
#import "NSData+JsonObject.h"

// AFURLResponseSerialization.m
static BOOL AFErrorOrUnderlyingErrorHasCodeInDomain(NSError *error, NSInteger code, NSString *domain) {
    if ([error.domain isEqualToString:domain] && error.code == code) {
        return YES;
    } else if (error.userInfo[NSUnderlyingErrorKey]) {
        return AFErrorOrUnderlyingErrorHasCodeInDomain(error.userInfo[NSUnderlyingErrorKey], code, domain);
    }
    
    return NO;
}

//static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) {
//    if ([JSONObject isKindOfClass:[NSArray class]]) {
//        NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]];
//        for (id value in (NSArray *)JSONObject) {
//            [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)];
//        }
//        
//        return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray];
//    } else if ([JSONObject isKindOfClass:[NSDictionary class]]) {
//        NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject];
//        for (id <NSCopying> key in [(NSDictionary *)JSONObject allKeys]) {
//            id value = (NSDictionary *)JSONObject[key];
//            if (!value || [value isEqual:[NSNull null]]) {
//                [mutableDictionary removeObjectForKey:key];
//            } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
//                mutableDictionary[key] = AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions);
//            }
//        }
//        
//        return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary];
//    }
//    
//    return JSONObject;
//}

@implementation YuanXinJSONResponseSerializer

#pragma mark - AFURLResponseSerialization

- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error
{
    NSError *responseError = nil;
    
    id responseObject = [super responseObjectForResponse:response data:data error:&responseError];
    if (responseError) {
        return [self responseNotJSONObjectForResponse:response data:data error:error];
    }
    
    return responseObject;
}

// 非json格式
- (id)responseNotJSONObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error
{
    if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
        if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
            return nil;
        }
    }
    
    // Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization.
    // See https://github.com/rails/rails/issues/1742
    BOOL isSpace = [data isEqualToData:[NSData dataWithBytes:" " length:1]];
    
    if (data.length == 0 || isSpace) {
        return nil;
    }
    
    NSError *serializationError = nil;
    
    NSString *responseText =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    id responseJsonObject = [data jsonObjectError:serializationError];
    
    id responseObject = nil;
    
    if (responseJsonObject) {
        responseObject = responseJsonObject;
    } else {
        responseObject = responseText;
    }
    
    /**
     Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`.
     */
    if (self.removesKeysWithNullValues) {
        return AFJSONObjectByRemovingKeysWithNullValues(responseObject, self.readingOptions);
    }
    
    return responseObject;
}

@end
